Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance of element handling #1601

Merged
merged 35 commits into from Aug 4, 2017
Merged

Conversation

baoilleach
Copy link
Member

As described over at openbabel/enhancement-proposals#4.

Briefly, the old element handling code had some performance problems. I have written a faster replacement. It has the following additional benefits:

  1. No need for a global etab or isotab and associated initialization.
  2. The elements are now available as consts (e.g. OBElements::Carbon) to replace functions such as IsCarbon().
  3. No need for text/header files in data dir.

Timing comparison: get the symbol for elements 1 to 100 and convert back to atomic number (repeat x10000). 0.82s old vs 0.02s new. A more realistic conversion is to just do carbon: 0.14s old vs 0.01s new.

void test_OBElements()
{
  clock_t start = clock();
  unsigned int tot = 0;
  for (unsigned int N = 0; N < 10000; ++N) {
    for (unsigned int i = 1; i < 100; ++i) {
      const char *elem = OBElements::GetSymbol(6);
      unsigned int atomic_num = OBElements::GetAtomicNum(elem);
      tot += atomic_num;
    }
  }
  clock_t stop = clock();
  double sum = (double)(stop - start) / CLOCKS_PER_SEC;
  printf("%.2f s\n", sum);
  
  OBElementTable etab;
  start = clock();
  tot = 0;
  for (unsigned int N = 0; N < 10000; ++N) {
    for (unsigned int i = 1; i < 100; ++i) {
      const char *elem = etab.GetSymbol(6);
      unsigned int atomic_num = etab.GetAtomicNum(elem);
      tot += atomic_num;
    }
  }
  stop = clock();
  sum = (double)(stop - start) / CLOCKS_PER_SEC;
  printf("%.2f s\n", sum);
}

@baoilleach
Copy link
Member Author

Updated timings, for the record, with 3 signif figures and 10x more iterations:

Timing comparison: get the symbol for elements 1 to 100 and convert back to atomic number (repeat x100000). 8.05s old vs 0.187s new. A more realistic conversion is to just do carbon: 1.34s old vs 0.078s new.

@baoilleach
Copy link
Member Author

Good to merge? Or not...?

@ghutchis ghutchis merged commit 4931b9a into openbabel:master Aug 4, 2017
@ghutchis
Copy link
Member

ghutchis commented Aug 4, 2017

Yep, it looks good. Sorry for the delay

@n-yoshikawa
Copy link
Contributor

Could you show me how to use OBElements in Python binding?
For example, how can I replace the following code?

import openbabel

etab = openbabel.OBElementTable()
print(etab.GetSymbol(6))

@baoilleach
Copy link
Member Author

baoilleach commented Jun 9, 2019 via email

@n-yoshikawa
Copy link
Contributor

n-yoshikawa commented Jun 9, 2019

I tried the following test.py in the current master,

from openbabel import openbabel
  
print(openbabel.OBElements.GetSymbol(6))

but it yielded the followng error.

$ python3 test.py 
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print(openbabel.OBElements.GetSymbol(6))
AttributeError: module 'openbabel.openbabel' has no attribute 'OBElements'

@baoilleach
Copy link
Member Author

baoilleach commented Jun 9, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants